"""
文件处理:
        查看,上传,下载,退出
    网络:
        socket tcp
"""

from socket import *
import sys, os, time

# 全局常量
ADDR = ("127.0.0.1", 18693)


# 文件处理
class FTPFileServer:
    def __init__(self, sockfd):
        self.__sockfd = sockfd  # 获取套接字, 间接获取服务器参数
    
    def do_list(self):
        """获取文件列表"""
        self.__sockfd.send(b'L')
        
        data = self.__sockfd.recv(9216).decode()
        
        # 服务器需要人为的添加消息边界(换行符),解决tcp沾包问题
        data_ = data.split(' ', 1)[0]
        data_1 = data.split(" ", 1)[1]
        if data_ == "ok":
            print(data_1)
        else:
            print(data)
    
    def do_quit(self):
        """退出"""
        self.__sockfd.send(b'Q')
        self.__sockfd.close()
        sys.exit("正常退出.")
        
    def do_get(self, name):
        """下载"""
        # 发送请求
        self.__sockfd.send(('G '+name).encode())
        # 等待回复
        data = self.__sockfd.recv(128).decode()
        if data == 'ok':
            f = open(name,'wb')
            # 循环接收内容,写入文件
            while True:
                data = self.__sockfd.recv(1024)
                if data == b'##': # 发送完成
                    break
                f.write(data)
            f.close()
        else:
            print(data)
        
    def do_put(self, name):
        """上传"""
        try:
            f = open(name, 'rb')
        except Exception:
            # c.send("打开失败,文件不存在".encode())
            print("打开失败,文件不存在!")
            return
            
        filename = name.split('/')[-1]
        
        self.__sockfd.send(f"P {filename}".encode())
        data = self.__sockfd.recv(128).decode()
        if data == 'ok':
            while True:
                date = f.read(1024)
                if not date:
                    time.sleep(0.1)
                    self.__sockfd.send(b'##')
                    
                self.__sockfd.send(date)
        else:
            print(data)


# 网络服务
class Mains:
    def __init__(self):
        self.__sockfd = socket()
        self.__ftp = FTPFileServer(self.__sockfd)
        
        self.start_()
        
        
    def start_(self):
        try:
            self.__sockfd.connect(ADDR)
        except Exception as e:
            print("失败: ", e)
            return
        
        while True:
            print("\n===========命令选项============")
            print("******   list(列表)           ******")
            print("******   get name(下载文件)   ******")
            print("******   put (上传文件)   ******")
            print("******   quit(退出)           ******")
            
            self.__select()
                
            # self.__sockfd.send(cmd.encode())
    
    def __select(self):
        try:
            cmd = input("输入命令>: ")
        except KeyboardInterrupt:
            sys.exit("退出程序.")
        
        if cmd.strip() == "list" or cmd.strip() == "列表":
            self.__ftp.do_list()
        elif cmd[:3] == "get": 
            # 去掉两边空格, 获取最后一个元素, 当然了如果是界面点击另算
            fliename = cmd.strip().split(" ")[-1]
            self.__ftp.do_get(fliename)
        elif cmd[:3] == "put":
            # files = os.listdir("./")
            # print(files)
            # da = input("输入文件名字>: ")
            flienames = cmd.strip().split(" ")[-1]
            self.do_put(flienames)
        elif cmd == "quit" or cmd.strip() == "退出":
            self.__ftp.do_quit()
        else:
            print("请按照格式输入!")
        

# 测试
if __name__ == "__main__":
    main = Mains()